#ifndef _Utils_H_
#define _Utils_H_

#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <iostream>
#include <cstring>
#include <cstdlib>

#include <time.h>

#if defined (WIN32) || defined (WIN64) // Windows-specific - BEGIN
#include <winsock2.h>

LONGLONG getmsec()
{
	LONGLONG t;
	GetSystemTimeAsFileTime((FILETIME*)&t);
	return t / 10 / 1000;
}
// Windows-specific - END

#else // Linux-specific - BEGIN
#include <pthread.h>
#include <sys/time.h>

typedef long long LONGLONG;
typedef int __time32_t;

#define INFINITE 0xFFFFFFFF

#define CRITICAL_SECTION				pthread_mutex_t
#define EnterCriticalSection			pthread_mutex_lock
#define LeaveCriticalSection			pthread_mutex_unlock
#define InitializeCriticalSection(x)	pthread_mutex_init(x, NULL)

LONGLONG getmsec()
{
	LONGLONG t;
	timeval now;
	gettimeofday (&now, 0);
	t = now.tv_sec * 1000 + now.tv_usec / 1000;
	return t;
}
inline void Sleep(unsigned long msec)
{
	usleep(msec*1000);
}
inline __time32_t _time32(__time32_t* tt32)
{
	time_t tt = time(0);
	if (tt32) *tt32 = __time32_t(tt);
	return __time32_t(tt);
}
inline int _stricmp(const char* str1, const char* str2)
{
	return strcasecmp(str1, str2);
}
#endif // Linux-specific - END

char* _gets(char* buf, int max)
{
	char* ret = fgets(buf, max, stdin);
	if (ret && strlen(ret)) ret[strlen(ret)-1] = '\0';
	return ret;
}

bool getArg(const char* argName, char** argVal, int* idx, int argc, char* argv[])
{
	int i = *idx;
	const char* arg = argv[i];
	if (_stricmp(arg, argName)) return false;
	if (++i >= argc) return false;
	*argVal = argv[i];
	*idx = i;
	return true;
}

bool readSubjectFile(const char* subjfile, std::vector<std::string>& subjects)
{
	std::ifstream fin(subjfile);
	if (!fin) {
		printf("Error: Failed to open file %s\n", subjfile);
		return false;
	}

	char subj[128];
	while (fin.getline(subj, sizeof(subj))) subjects.push_back(subj);

	return true;
}

const char* makeSessionName(const char* partname, char* fullname)
{
	char hostname[64];
	gethostname(hostname, sizeof(hostname));
    std::cout << hostname << std::endl;
	sprintf(fullname, "%s@%s", partname, hostname);
	return fullname;
}

class CStringComparator
{
public:
	bool operator()(const char* s1, const char* s2) const {
		return strcmp(s1, s2) < 0;
	}
};

#endif
